﻿using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Activities;
using System.Activities.Expressions;
using System.Activities.Presentation.PropertyEditing;
using System.Activities.Statements;
using System.Collections.Generic;
using System.ComponentModel;
using Core = Vision.Core;

namespace Vision.Core.ActivityComponents.IO.File
{
    /// <summary>
    /// 
    /// </summary>
    [System.ComponentModel.Designer(typeof(FileListDesigner))]
    public class FileList : NativeActivity
    {
        /// <summary>
        /// 
        /// </summary>
        [Browsable(false)]
        [DefaultValue(null)]
        public ActivityAction<System.IO.FileInfo> Body { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [DefaultValue("")]        
        public InArgument<string> DirectoryPath { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [DefaultValue("")]
        public InArgument<string> SearchPattern { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [DefaultValue(false)]
        public InArgument<bool> IncludeSubDirectories { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [Category("Input")]
        [DefaultValue(OrderBy.None)]
        public OrderBy SortOrder { get; set; }
        
        /// <summary>
        /// 
        /// </summary>
        public FileList() : base()
        {
            this.Body = new ActivityAction<System.IO.FileInfo>(){
                Argument = new DelegateInArgument<System.IO.FileInfo>() { Name = "file" }
            };                        
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="context"></param>
        protected override void Execute(NativeActivityContext context)
        {
            if (this.Body != null){                
                List<string> fileList = new List<string>();

                //Get File List:
                System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(this.DirectoryPath.Get(context));
                System.IO.FileInfo[] files = di.GetFiles();
                if (this.SearchPattern.Get(context) != null){
                    SearchOption so = SearchOption.TopDirectoryOnly;
                    if (this.IncludeSubDirectories.Get(context) == true){
                        so = SearchOption.AllDirectories;
                    }
                    files = di.GetFiles(this.SearchPattern.Get(context), so);
                }

                //Order Files:
                switch (this.SortOrder){
                    case OrderBy.Name:
                        files = files.OrderBy(f => f.Name).ToArray();
                        break;
                    case OrderBy.CreationTime:
                        files = files.OrderBy(f => f.CreationTime).ToArray();
                        break;
                    case OrderBy.LastAccessTime:
                        files = files.OrderBy(f => f.LastAccessTime).ToArray();
                        break;
                    case OrderBy.LastWriteTime:
                        files = files.OrderBy(f => f.LastWriteTime).ToArray();
                        break;
                }

                foreach (System.IO.FileInfo file in files){                                        
                    context.ScheduleAction(this.Body, file);
                }

                di = null;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public enum OrderBy
        {
            None,
            Name,
            CreationTime,
            LastAccessTime,
            LastWriteTime
        }
    }
}
